﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace Microsoft.Windows.Controls.Specialized.Primitives {

    public class TextStyle: IEquatable<TextStyle> {
        private FontFamily _fontFamily;
        private double? _fontSize;
        private FontStretch? _fontStretch;
        private FontStyle? _fontStyle;
        private FontWeight? _fontWeight;
        private Brush _foreground;
        private TextDecorationCollection _textDecorations;

        public FontFamily FontFamily {
            get {
                if (_fontFamily == null && BasedOn != null)
                    return BasedOn.FontFamily;
                return _fontFamily;
            }
            set { 
                _fontFamily = value; 
            }
        }

        public double? FontSize {
            get {
                if (_fontSize == null && BasedOn != null)
                    return BasedOn.FontSize;
                return _fontSize;
            }
            set {
                _fontSize = value;
            }
        }

        public FontStretch? FontStretch {
            get {
                if (_fontStretch == null && BasedOn != null)
                    return BasedOn.FontStretch;
                return _fontStretch;
            }
            set {
                _fontStretch = value;
            }
        }

        public FontStyle? FontStyle {
            get {
                if (_fontStyle == null && BasedOn != null)
                    return BasedOn.FontStyle;
                return _fontStyle;
            }
            set {
                _fontStyle = value;
            }
        }

        public FontWeight? FontWeight {
            get {
                if (_fontWeight == null && BasedOn != null)
                    return BasedOn.FontWeight;
                return _fontWeight;

            }
            set {
                _fontWeight = value;
            }
        }

        public Brush Foreground { 
            get {
                if (_foreground == null && BasedOn != null)
                    return BasedOn.Foreground;
                return _foreground;
            }
            set {
                _foreground = value;
            }
        }

        public TextDecorationCollection TextDecorations {
            get {
                if (_textDecorations == null && BasedOn != null)
                    return BasedOn.TextDecorations;
                return _textDecorations;
            }
            set {
                _textDecorations = value;
            }
        }

        public TextStyle BasedOn { get; set; }

        public void ApplyTo(Inline inline) {
            if (FontFamily != null)
                inline.FontFamily = FontFamily;
            if (FontSize.HasValue)
                inline.FontSize = FontSize.Value;
            if (FontStretch.HasValue)
                inline.FontStretch = FontStretch.Value;
            if (FontStyle.HasValue)
                inline.FontStyle = FontStyle.Value;
            if (FontWeight.HasValue)
                inline.FontWeight = FontWeight.Value;
            if (Foreground != null)
                inline.Foreground = Foreground;
            if (TextDecorations != null)
                inline.TextDecorations = TextDecorations;            
        }

        public override bool Equals(object obj) {
            return Equals(obj as TextStyle);
        }

        public override int GetHashCode() {
            return unchecked(typeof(TextStyle).GetHashCode() + 
                (FontFamily != null ? FontFamily.GetHashCode() : 0) +
                (FontSize.HasValue ? FontSize.Value.GetHashCode() : 0) +
                (FontStretch.HasValue ? FontStretch.Value.GetHashCode() : 0) +
                (FontStyle.HasValue ? FontStyle.Value.GetHashCode() : 0) +
                (FontWeight.HasValue ? FontWeight.Value.GetHashCode() : 0) +
                (Foreground != null ? Foreground.GetHashCode() : 0) +
                (TextDecorations != null ? TextDecorations.GetHashCode() : 0));
        }

        public static TextStyle Default = new TextStyle();

        #region IEquatable<TextStyle> Members

        public bool Equals(TextStyle other) {
            if (other != null) {
                if (FontFamily != other.FontFamily) return false;
                if (FontSize != other.FontSize) return false;
                if (FontStretch != other.FontStretch) return false;
                if (FontWeight != other.FontWeight) return false;
                if (Foreground != other.Foreground) return false;
                if (TextDecorations != other.TextDecorations) return false;
                return true;
            }
            return false;
        }

        #endregion
    }
}
